
#include<iostream>
#include<string>
#include<unistd.h>
#include<sys/types.h>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<functional>
//1.我们自己就是master
using namespace std;
using work_t = std::function<void()>;

enum
{
  OK=0,
  UsageError,
  PipeError,
  ForkError
};

//先描述
class Channel
{
public:
  Channel(int wfd,pid_t who):_wfd(wfd),_who(who)
  {
     _name = "Channel-" + to_string(wfd) + "-" + to_string(who);
  }
  string Name()
  {
    return _name;
  }
  ~Channel()
  {}

private:
    int _wfd; //需要向子进程写 所以保存写端
    string _name;  //管道名字
    pid_t _who;//给哪个子进程建立的管道
};

void Worker()
{
  sleep(10);
}

void Print()
{

}

void DownLoad()
{

}

void Log()
{

}

void Usage(string proc)
{
    cout << "Usage: " << proc << "process-num" << endl;
}

void DebugPrint(vector<Channel>& channels)
{
  for( auto&  c : channels)
  {
     cout << c.Name() << endl;
  }
}

//channels输出型参数
//work_t work:回调函数
int InitPorcessPool(const int& num,vector<Channel>& channels,work_t work)
{
      for(int i = 0 ; i < num ; i++)
     {
        //1.创建管道
        int pipefd[2] = {0};
        int n = pipe(pipefd);
        if(n < 0) return PipeError;   //管道创建失败
         //2.管道创建成功，创建子进程
        pid_t id = fork();
        if(id < 0) return ForkError; //创建子进程失败
        if(id == 0) //child
        {
           ::close(pipefd[1]); //子进程关闭写
           dup2(pipefd[0],0);
           work();//工作
           exit(0); //工作做完直接结束只会完成任务
        }
           //father
        ::close(pipefd[0]);
        channels.emplace_back(pipefd[1],id);
     }
     return OK;
}



int main(int argc,char* argv[])
{
     if(argc != 2) //表示没按规定格式用
     {
        Usage(argv[0]);
        return UsageError;
     }
     int num = stoi(argv[1]); //要创建进程个数
     vector<Channel> channels;
     InitPorcessPool(num,channels,Worker); 
     DebugPrint(channels);
     sleep(30);
    return 0;
}